package com.cloud.phone.tools;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Path;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;

import com.cloud.phone.constants.Constants;
import com.cloud.phone.service.AccessibilityAutoMainService;
import com.cloud.phone.task.MsgTaskManger;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

//无障碍通用工具
public class AccessibilityTool{
    private static AccessibilityTool tool;

    /**
     * 获取单例
     * @return
     */
    public static AccessibilityTool getInstance(){
        if(tool==null){
            tool=new AccessibilityTool();
        }
        return tool;
    }





    /*
     * 连续点击两次返回按钮
     */
    public void backTwo(AccessibilityService accessibilityService){
        LogUtils.d("关闭所有，回到桌面");
        accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
            }
        },150);
    }


    /**
     * 判断是否进入tiktok
     * @return
     */
    public boolean checkIsEnterInTikTok(AccessibilityService service){
        if(Constants.tiktokPackageName.equals(AccessibilityTool.getInstance().getCurrentPagePackageName(service))){
            return true;
        }
        return false;
    }

    public boolean checkIsEnterInWhatsApp(AccessibilityService service){
        if(Constants.whatsAppPackageName.equals(AccessibilityTool.getInstance().getCurrentPagePackageName(service))){
            return true;
        }
        return false;
    }



    /**
     * 获取当前页面的包名
     * @param service
     * @return
     */
    public String getCurrentPagePackageName(AccessibilityService service){
        if(getRootNodeInfo(service)==null){
            return "";
        }
        try {
            return (String) getRootNodeInfo(service).getPackageName();
        }catch (Exception e){
            e.printStackTrace();
        }
        return "";
    }


    /*
     * 连续点击两次返回按钮
     */
    public void backOnce(AccessibilityService accessibilityService){
        accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
    }


    /**
     * 手势滑动
     * @param accessibilityService
     * @param x
     * @param y
     * @param lastX
     * @param lastY
     * @param duration
     */
    public void swipe(AccessibilityService accessibilityService,int x,int y,int lastX,int lastY,long duration) {
       swipe(accessibilityService, x, y, lastX, lastY, duration, new AccessibilityService.GestureResultCallback() {
           @Override
           public void onCompleted(GestureDescription gestureDescription) {
               super.onCompleted(gestureDescription);
           }
       });
    }


    /**
     * 滑动带监听
     * @param accessibilityService
     * @param duration
     * @param callback
     */
    public void swipe(AccessibilityService accessibilityService,int fromX,int fromY,int toX,int toY,long duration,AccessibilityService.GestureResultCallback callback) {
        GestureDescription.Builder builder = new GestureDescription.Builder();
        Path path = new Path();
        path.moveTo(fromX, fromY);
        path.lineTo(toX, toY);
        GestureDescription gestureDescription = builder
                .addStroke(new GestureDescription.StrokeDescription(path, 100, duration))
                .build();
        accessibilityService.dispatchGesture(gestureDescription,
                callback, null);
    }


    /**
     * 设置输入框之类节点的文字信息
     * @param node
     * @param text
     */
    public void setNodeText(AccessibilityNodeInfo node, String text)
    {
        Bundle arguments = new Bundle();
        arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
        node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
    }


    /**
     * 获取当前根节点对象
     * @param accessibilityService
     * @return
     */
    public AccessibilityNodeInfo getRootNodeInfo(AccessibilityService accessibilityService) {
        AccessibilityNodeInfo nodeInfo = null;
        if(accessibilityService==null){
            MsgTaskManger.showLog("service is null");
            return null;
        }
        List<AccessibilityWindowInfo> accessibilityWindows = accessibilityService.getWindows();
        if(!MyUtils.isEmpty(accessibilityWindows)){
            for(AccessibilityWindowInfo accessibilityWindowInfo:accessibilityWindows){
                if(accessibilityWindowInfo.isAccessibilityFocused()&&accessibilityWindowInfo.isActive()&&accessibilityWindowInfo.getRoot()!=null){
                    return accessibilityWindowInfo.getRoot();
                }
            }
        }
        nodeInfo = accessibilityService.getRootInActiveWindow();
        return nodeInfo;
    }


    /**
     * 通过文字查询根节点下的所有节点列表,必须完全匹配文字
     * @return
     */
    public List<AccessibilityNodeInfo> findNodesByText(List<AccessibilityNodeInfo> nodesList,AccessibilityNodeInfo nodeInfo,AccessibilityService accessibilityAutoMainService,String eqText) {
        if(nodeInfo==null) {
            nodeInfo = AccessibilityTool.getInstance().getRootNodeInfo(accessibilityAutoMainService);
        }
        if(MyUtils.isEmpty(nodesList)){
            nodesList=new ArrayList<>();
        }
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            // 处理子节点信息，例如打印节点名称
            CharSequence className = nodeInfo.getClassName();
            CharSequence text = nodeInfo.getText();
            CharSequence viewIdName = nodeInfo.getViewIdResourceName();
            if(text!=null&&eqText.contentEquals(text)){
                nodesList.add(nodeInfo);
            }
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
                if (childNode != null) {
                    // 递归遍历子节点的子节点（如果需要）
                    nodesList=findNodesByText(nodesList,childNode, accessibilityAutoMainService, eqText);
                }
            }
            return nodesList;
        }
        return null;
    }





    /**
     * 返回该节点是否存在或有效
     * @param nodes
     * @return
     */
    public boolean isNodeExist(List<AccessibilityNodeInfo> nodes) {
        if(nodes!=null&& !nodes.isEmpty()){
            return true;
        }
        return false;
    }


    /**
     * 通过类名查找节点
     * @param nodeInfo
     * @param tagClassName
     * @return
     */
    public List<AccessibilityNodeInfo> findNodeInfoByClassName(List<AccessibilityNodeInfo> nodesList,AccessibilityNodeInfo nodeInfo,AccessibilityAutoMainService accessibilityAutoMainService,String tagClassName){
        if(nodeInfo==null) {
            nodeInfo = AccessibilityTool.getInstance().getRootNodeInfo(accessibilityAutoMainService);
        }
        if(MyUtils.isEmpty(nodesList)){
            nodesList=new ArrayList<>();
        }
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            // 处理子节点信息，例如打印节点名称
            CharSequence className = nodeInfo.getClassName();
            LogUtils.w("类名："+className+",tagName:"+tagClassName);
            CharSequence text = nodeInfo.getText();
            CharSequence viewIdName = nodeInfo.getViewIdResourceName();
            if(className!=null&&tagClassName.contentEquals(className)){
                nodesList.add(nodeInfo);
            }
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
                if (childNode != null) {
                    // 递归遍历子节点的子节点（如果需要）
                    nodesList=findNodeInfoByClassName(nodesList,childNode, accessibilityAutoMainService, tagClassName);
                }
            }
            return nodesList;
        }
        return null;
    }







    public List<AccessibilityNodeInfo> findNodesByIdPlus(List<AccessibilityNodeInfo> nodesList,AccessibilityNodeInfo nodeInfo,AccessibilityAutoMainService accessibilityAutoMainService,String resId){
        if(nodeInfo==null) {
            nodeInfo = AccessibilityTool.getInstance().getRootNodeInfo(accessibilityAutoMainService);
        }
        if(MyUtils.isEmpty(nodesList)){
           nodesList=new ArrayList<>();
        }
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            // 处理子节点信息，例如打印节点名称
            String className = nodeInfo.getClassName().toString();
            CharSequence text = nodeInfo.getText();
            CharSequence viewIdName = nodeInfo.getViewIdResourceName();
            if(viewIdName!=null&&resId.contentEquals(viewIdName)){
                nodesList.add(nodeInfo);
            }
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
                if (childNode != null) {
                    // 递归遍历子节点的子节点（如果需要）
                    nodesList=findNodesByIdPlus(nodesList,childNode, accessibilityAutoMainService, resId);
                }
            }
            return nodesList;
        }
        return null;
    }




    public String findNodeInfoAllInPage(String result,AccessibilityNodeInfo nodeInfo,AccessibilityAutoMainService accessibilityAutoMainService,String prefix,boolean isLast){
        if(nodeInfo==null) {
            nodeInfo = AccessibilityTool.getInstance().getRootNodeInfo(accessibilityAutoMainService);
        }
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            String marker = isLast?"\\--- ": "+---";
            String currentPrefix = prefix+marker;
            // 处理子节点信息，例如打印节点名称
            String className = nodeInfo.getClassName().toString();
            CharSequence text = nodeInfo.getText();
            CharSequence viewIdName = nodeInfo.getViewIdResourceName();
            String childPrefix = prefix + (isLast?"  " : "|  ");
            Log.v("printNodeInfo", currentPrefix +"className:"+ className+",id: " + viewIdName+ ", Text: " + text);
            result+=currentPrefix +"className:"+ className+",id: " + viewIdName+ ", Text: " + text;
            result+="\n";
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
                if (childNode != null) {
                    // 递归遍历子节点的子节点（如果需要）
                    result=findNodeInfoAllInPage(result,childNode,accessibilityAutoMainService,childPrefix,i==childCount-1);
                }
            }
        }
        return result;
    }



    /**
     * 查询根节点下对于id的节点对象
     * @param accessibilityService
     * @param viewId
     * @return
     */
    public AccessibilityNodeInfo findNodeFirstById(AccessibilityService accessibilityService, String viewId) {
        List<AccessibilityNodeInfo> nodes = findNodesById(accessibilityService,viewId);
        if(MyUtils.isEmpty(nodes)){
            return null;
        }
        List<AccessibilityNodeInfo> visibleNodes=new ArrayList<>();
        for(int i=0;i<nodes.size();i++){
            if(nodes.get(i).isVisibleToUser()){
                visibleNodes.add(nodes.get(i));
            }
        }
        if(isNodeExist(visibleNodes)){
            return visibleNodes.get(0);
        }
        return null;
    }


    public AccessibilityNodeInfo findNodeIndexById(AccessibilityService accessibilityService,int index, String viewId) {
        List<AccessibilityNodeInfo> nodes = findNodesById(accessibilityService,viewId);
        if(MyUtils.isEmpty(nodes)){
            return null;
        }
        List<AccessibilityNodeInfo> visibleNodes=new ArrayList<>();
        for(int i=0;i<nodes.size();i++){
            if(nodes.get(i).isVisibleToUser()){
                visibleNodes.add(nodes.get(i));
            }
        }
        if(isNodeExist(visibleNodes)){
            if(visibleNodes.size()>index){
                return visibleNodes.get(index);
            }
            return visibleNodes.get(0);
        }
        return null;
    }

    public AccessibilityNodeInfo findNodeFirstById(AccessibilityNodeInfo nodeInfo, String viewId) {
        if (nodeInfo != null) {
            List<AccessibilityNodeInfo> allNodes = findNodesById(nodeInfo,viewId);
            if(MyUtils.isEmpty(allNodes)){
                return null;
            }
            List<AccessibilityNodeInfo> visibleNodes=new ArrayList<>();
            for(int i=0;i<allNodes.size();i++){
                if(allNodes.get(i).isVisibleToUser()){
                    visibleNodes.add(allNodes.get(i));
                }
            }
            if(isNodeExist(visibleNodes)){
                return visibleNodes.get(0);
            }
        }
        return null;
    }


    public List<AccessibilityNodeInfo> findNodesById(AccessibilityService service, String viewId) {
        if (service != null&&getRootNodeInfo(service)!=null) {
            List<AccessibilityNodeInfo> allNodes = findNodesById(getRootNodeInfo(service),viewId);
            if(MyUtils.isEmpty(allNodes)){
                return null;
            }
            List<AccessibilityNodeInfo> visibleNodes=new ArrayList<>();
            for(int i=0;i<allNodes.size();i++){
                if(allNodes.get(i).isVisibleToUser()){
                    visibleNodes.add(allNodes.get(i));
                }
            }
            return visibleNodes;
        }
        return null;
    }

    public List<AccessibilityNodeInfo> findNodesById(AccessibilityNodeInfo nodeInfo, String viewId) {
        if (nodeInfo != null) {
            List<AccessibilityNodeInfo> allNodes = nodeInfo.findAccessibilityNodeInfosByViewId(viewId);
            if(MyUtils.isEmpty(allNodes)){
                return null;
            }
            List<AccessibilityNodeInfo> visibleNodes=new ArrayList<>();
            for(int i=0;i<allNodes.size();i++){
                if(allNodes.get(i).isVisibleToUser()){
                    visibleNodes.add(allNodes.get(i));
                }
            }
            return visibleNodes;
        }
        return null;
    }


    public boolean longClickScreen(AccessibilityService service,int x1, int y1) {
        int mWidth = 1440;
        int mHeight = 3040;
        Path path=new Path();
        x1 = x1 + new Random().nextInt(9) - 4;
        y1 = y1 + new Random().nextInt(9) - 4;
        if (x1 > mWidth || y1 > mHeight || x1 < 0 || y1 < 0) {
            LogUtils.v("Variable.mWidth: " + mWidth);
            LogUtils.v("Variable.mHeight: " + mHeight);
            LogUtils.e("超出了点击范围");
            return false;
        }
        path.moveTo(x1, y1);
        GestureDescription.Builder builder=new GestureDescription.Builder();
        GestureDescription gestureDescription=builder
                .addStroke(new GestureDescription.StrokeDescription(path,0,new Random().nextInt(55) + 2000))
                .build();

        return service.dispatchGesture(gestureDescription,new AccessibilityService.GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription1) {
                super.onCompleted(gestureDescription1);
            }
            @Override
            public void onCancelled(GestureDescription gestureDescription1) {
                super.onCancelled(gestureDescription1);
            }
        },null);
    }



    /*功能
     * 1.坐标点击clickScreen()
     * 2.截屏及保存
     * */

    // 模拟点击屏幕500，500的坐标
    public boolean clickScreen(AccessibilityService service,int x1, int y1) {
        int mWidth = 1440;
        int mHeight = 3040;
        Path path=new Path();
        x1 = x1 + new Random().nextInt(9) - 4;
        y1 = y1 + new Random().nextInt(9) - 4;
        if (x1 > mWidth || y1 > mHeight || x1 < 0 || y1 < 0) {
            LogUtils.v("Variable.mWidth: " + mWidth);
            LogUtils.v("Variable.mHeight: " + mHeight);
            LogUtils.e("超出了点击范围");
            return false;
        }
        path.moveTo(x1, y1);
        GestureDescription.Builder builder=new GestureDescription.Builder();
        GestureDescription gestureDescription=builder
                .addStroke(new GestureDescription.StrokeDescription(path,0,new Random().nextInt(55) + 60))
                .build();

        return service.dispatchGesture(gestureDescription,new AccessibilityService.GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription1) {
                super.onCompleted(gestureDescription1);
            }
            @Override
            public void onCancelled(GestureDescription gestureDescription1) {
                super.onCancelled(gestureDescription1);
            }
        },null);
    }



    /**
     * 点击对应的节点
     */
    public boolean longClick(AccessibilityNodeInfo node) {
        if (node == null) {
            return false;
        }
        try {
            boolean action1 = node.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
            if (action1) {
                // 回收
                node.recycle();
                return true;
            }

            while (!node.isClickable()) {
                node = node.getParent();
            }
            if (node.isClickable()) {
                boolean action = node.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                // 回收
                node.recycle();
                return action;
            }
        }catch (Exception e) {}
        return false;
    }


    /**
     * 点击对应的节点
     */
    public boolean click(AccessibilityNodeInfo node) {
        if (node == null) {
            return false;
        }
        try {
            boolean action1 = node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            if (action1) {
                // 回收
                node.recycle();
                return true;
            }

            while (!node.isClickable()) {
                node = node.getParent();
            }
            if (node.isClickable()) {
                boolean action = node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                // 回收
                node.recycle();
                return action;
            }
        }catch (Exception e) {}
        return false;
    }



    //判断自定义辅助功能服务是否开启
    public boolean isAccessibilityServiceEnabled(Context context,String serviceComponentName){
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (activityManager != null) {
            List<ActivityManager.RunningServiceInfo> runningServices =
                    activityManager.getRunningServices(100);// 获取正在运行的服务列表
            if (runningServices.size() < 0) {
                return false;
            }
            for (int i = 0; i < runningServices.size(); i++) {
                ComponentName service = runningServices.get(i).service;
                if (service.getClassName().equals(serviceComponentName)) {
                    return true;
                }
            }
            return false;
        } else {
            return false;
        }
    }



}
